package com.weipai.education.service.impl;

import com.weipai.education.dao.*;
import com.weipai.education.enums.RetCode;
import com.weipai.education.enums.UserFlag;
import com.weipai.education.enums.UserStatus;
import com.weipai.education.enums.UserType;
import com.weipai.education.model.*;
import com.weipai.education.model.api.PageResult;
import com.weipai.education.model.api.Response;
import com.weipai.education.service.UserService;
import com.weipai.education.utils.GenerateUserAccountNumberUtils;
import com.weipai.education.utils.PasswordHelper;
import com.weipai.education.utils.SessionUserUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @Author: 曹朋飞
 * @Date: 2018/12/10 15:51
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserAddressDao userAddressDao;
    @Autowired
    private UserCategoryDao userCategoryDao;
    @Autowired
    private UserEarningsDao userEarningsDao;
    @Autowired
    private SessionUserUtil sessionUserUtil;
    @Autowired
    private SystemDao systemDao;

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Response save(User user) {
        Response response = new Response();
        if (1 != user.getType()) {
            response.setCode(RetCode.SELL_USER);
            return response;
        }
        if (null != user.getId()) {
            userDao.update(user);
        } else {
            User userOld = userDao.getUserByMobile(user.getMobile());
            if (null != userOld) {
                response.setCode(RetCode.USER_MOBILE);
                return response;
            }

            //判断此加盟商是否可以加入系统
            boolean fls = verifyUser(user);
            if (fls == false) {
                response.setCode(RetCode.NOT_USE);
                return response;
            }

            //superiorId 1说能看我提交的采购单 2结算时候判断上级是不是平台
//            String userId = sessionUserUtil.getUser().getId().toString();
            User referrerUser = userDao.selectByPrimaryKey(user.getReferrerId().toString()); //推荐人的信息
            if (Integer.valueOf(referrerUser.getType()) == Integer.valueOf(UserType.SELL_USER.getType())) {  //推荐人的身份是经销商
                if (Integer.valueOf(referrerUser.getFlag()) == Integer.valueOf(UserFlag.ELSE.getType())) { //我的推荐人的级别 0其他身份 即创客和联盟校
                    //所在地区的区级加盟商作为我的开通人，能查看我提交的订单信息
                    User user1 = userDao.getUserByAddress(UserFlag.DISTRICT_LEVEL_AGENTS.getType(), user.getProvince(), user.getCity(), user.getCounty());
                    if (null != user1 && user.getFlag() != UserFlag.THE_MUNICIPAL_AGENTS.getType() && user.getFlag() != UserFlag.THE_MUNICIPAL_AGENTS.getType()) {
                        user.setSuperiorId(user1.getId());
                    } else { //所在地区没有区级，开通人默认为平台
                        user.setSuperiorId(-1);
                    }
                } else {  //我的推荐人身份是旗舰，市级，区县的话能看我的采购信息
                    user.setSuperiorId(user.getReferrerId()); //我的推荐人能看我的
                }
            } else { //推荐人是总部账号
                user.setSuperiorId(-1);
            }
            String account = GenerateUserAccountNumberUtils.generaateUserAccountNumber();
            user.setStatus(0);
            user.setRecommendReward(new BigDecimal(0));
            user.setGoodsReward(new BigDecimal(0));
            user.setIsAudit(1);
            user.setPassword(PasswordHelper.encryptPassword(user.getPassword(), account));
            user.setAccountNumber(account);
            userDao.insert(user);

            //我的推荐人
//            User referrerUser = userDao.selectByPrimaryKey(Integer.toString(user.getReferrerId()));

            //推荐人总部账号，是总部直接开通的，不走分润
            if (referrerUser.getType() == UserType.SELL_USER.getType()) {
                //我的加盟费用
                UserCategory userCate = userCategoryDao.selectByPrimaryKey(Integer.toString(user.getUserCateId()));
                Integer joinFee = userCate.getJoinFee();
                if (joinFee > 0) {  //加盟费
                    //推荐奖
                    recommendReward(user, joinFee);

                    //区域占地奖
                    areaReward(user, joinFee);
                }
            }
        }
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    /**
     * 判断此加盟商是否可以加入系统
     *
     * @param user
     */
    private boolean verifyUser(User user) {

        int flag = user.getFlag();
        int num = 0;
        if (flag == UserFlag.DISTRICT_LEVEL_AGENTS.getType()) {
            //区级
            num = userDao.verifyUserByAddress(flag, user.getProvince(), user.getCity(), user.getCounty());
        } else if (flag == UserFlag.THE_MUNICIPAL_AGENTS.getType()) {
            //市级
            num = userDao.verifyUserByAddress(flag, user.getProvince(), user.getCity(), null);
        }
        if (num > 0) {
            return false;
        }
        return true;
    }

    /**
     * 分润--区域奖
     *
     * @param user
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void areaReward(User user, Integer joinFee) {
        //查询我上面的代理
        User referrerUser = userDao.selectByPrimaryKey(Integer.toString(user.getReferrerId()));
//        int i = referrerUser.getFlag();
//        我所在区域的上级
//        User userSuperior = userDao.getCityCountyUser(referrerUser.getProvince(),referrerUser.getCity(), referrerUser.getCounty(), i);

        //获取推荐人的城市
        String city = referrerUser.getCity();
        //获取被推荐人的城市
        String usercity = user.getCity();
        if (!usercity.equals(city)) {
            //异地推荐的100元
            saveUserEarnings(user.getReferrerId(), new BigDecimal(100), 6, user.getId());
            addMessage(user,new BigDecimal(100),referrerUser.getId());
        }

//        if (null != userSuperior ) {
            //if(userSuperior.getId()!=user.getId()){ }
            //搜索我所在地区的区级代表
            User user1 = userDao.getUserByAddress(UserFlag.DISTRICT_LEVEL_AGENTS.getType(), user.getProvince(), user.getCity(), user.getCounty());
            if(user1 != null){ //有区县代理
                if(user1.getType() == UserType.SELL_USER.getType()){  //区县代表不是平台账户
                    //我所在区域的区县的比例
                    UserCategory referrerUserCate = userCategoryDao.selectByPrimaryKey(Integer.toString(user1.getUserCateId()));

                    //我上级的提成比例
                    Integer areaRate = referrerUserCate.getAreaRate();

                    //计算上级应得的推荐奖
                    BigDecimal a = new BigDecimal(areaRate).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
                    BigDecimal c = new BigDecimal(joinFee).multiply(a);
                    user1.setRecommendReward(user1.getRecommendReward().add(c));

                    userDao.updateByPrimaryKeySelective(user1);
                    addMessage(user,c,user1.getId());
                    //奖金记录
                    saveUserEarnings(user1.getId(), c, 5, user.getId());
                }
            }
            //搜索我所在地区的市级代表
            User user2 = userDao.getUserByAddress(UserFlag.THE_MUNICIPAL_AGENTS.getType(), user.getProvince(), user.getCity(), null);
            if(user2 != null){ //有区县代理
                if(user2.getType() == UserType.SELL_USER.getType()){  //区县代表不是平台账户
                    //我所在区域的区县的比例
                    UserCategory referrerUserCate = userCategoryDao.selectByPrimaryKey(Integer.toString(user1.getUserCateId()));

                    //我上级的提成比例
                    Integer areaRate = referrerUserCate.getAreaRate();

                    //计算上级应得的推荐奖
                    BigDecimal a = new BigDecimal(areaRate).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
                    BigDecimal c = new BigDecimal(joinFee).multiply(a);
                    user2.setRecommendReward(user2.getRecommendReward().add(c));

                    userDao.updateByPrimaryKeySelective(user2);
                    addMessage(user,c,user2.getId());
                    //奖金记录
                    saveUserEarnings(user2.getId(), c, 5, user.getId());
                }
            }
//        }

    }


    /**
     * 分润--推荐奖
     *
     * @param user
     * @param joinFee
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void recommendReward(User user, Integer joinFee) {

        //我的推荐人
        User referrerUser = userDao.selectByPrimaryKey(Integer.toString(user.getReferrerId()));

        //我的推荐人类别
        UserCategory referrerUserCate = userCategoryDao.selectByPrimaryKey(Integer.toString(referrerUser.getUserCateId()));

        //我上级的提成比例
        Integer recommendRate = referrerUserCate.getRecommendRate();

        //计算上级应得的推荐奖
        BigDecimal a = new BigDecimal(recommendRate).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal c = new BigDecimal(joinFee).multiply(a);
        referrerUser.setRecommendReward(referrerUser.getRecommendReward().add(c));

        userDao.updateByPrimaryKeySelective(referrerUser);

        addMessage(user,c,referrerUser.getId());

        //奖金记录
        saveUserEarnings(referrerUser.getId(), c, 1, user.getId());
    }

    /**
     * 奖金记录
     *
     * @param userId：得奖人id
     * @param rewardPrice：奖金
     * @param type：1推荐奖，2占地加盟奖
     * @param offerUserId：新人
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void saveUserEarnings(Integer userId, BigDecimal rewardPrice, Integer type, Integer offerUserId) {
        UserEarnings earnings = new UserEarnings();
        earnings.setUserId(userId).setRewardPrice(rewardPrice).setType(type)
                .setOfferUserId(offerUserId);
        userEarningsDao.insert(earnings);
    }

    @Override
    /**
     * user 被推荐人的信息
     * price 分成的钱
     * userId 推荐人的id
     */
    public void addMessage(User user,BigDecimal price,Integer userId ){
        //添加消息通知记录
        Message message = new Message();
        message.setUserId(userId).setRecommendId(user.getId()).setContent("您成功推荐1位客户[" + user.getNickname() + "]成为妈仔智教加盟商，获得推荐奖励"+ price).setType(4).setSign(0);
        systemDao.insertMsg(message);
    }

    @Override
    public Response changeStatus(String id) {
        Response response = new Response();
        User user = userDao.selectByPrimaryKey(id);
        if (null != user) {
            if (0 == user.getStatus()) {
                user.setStatus(-1);
            } else {
                user.setStatus(0);
            }
            userDao.update(user);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response list(Integer page, Integer size, Integer userCateId, String key, String type) {
        Response response = new Response();

        String userId = null;
        if (type != null) {
            //从session中获取userId
            userId = sessionUserUtil.getUser().getId().toString();
        }
        Integer start = (page - 1) * size;
        List<Map<String, Object>> user = userDao.list(start, size, userCateId, key, userId);
        Integer totalNum = userDao.listAmount(userCateId, key, userId);
        PageResult<Map<String, Object>> pageList = new PageResult<>(user, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    public Response Mylist(Integer page, Integer size, Integer userCateId, String key, String type) {
        Response response = new Response();

        String userId = null;
        if (type != null) {
            //从session中获取userId
            userId = sessionUserUtil.getUser().getId().toString();
        }

        Integer start = (page - 1) * size;
        List<Map<String, Object>> user = userDao.Mylist(start, size, userCateId, key, userId);
        Integer totalNum = userDao.MylistAmount(userCateId, key, userId);
        if (totalNum==0){
            response.setCode(RetCode.No_ALLIANCEBUSINESS);
            return response;
        }
        PageResult<Map<String, Object>> pageList = new PageResult<>(user, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    public Response isAudit(String id, String isAudit) {
        Response response = new Response();
        ApplicationUser applicationUser = userDao.selectApplicationUserByPrimaryKey(id);
        if (null != applicationUser) {
            applicationUser.setIsAudit(Integer.parseInt(isAudit));
            userDao.updateApplicationUser(applicationUser);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response batchDeleteById(String[] id) {
        Response response = new Response();
        if (userDao.batchDeleteById(id) > 0) {
            //经销商删除，考虑关联的信息删除
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.REQUEST_ERROR);
        }
        return response;
    }

    @Override
    public Response applicationUser(ApplicationUser applicationUser) {
        Response response = new Response();

        //从session中获取登录人id
        String userId = sessionUserUtil.getUser().getId().toString();

        User user = userDao.getUserModelByAccountNumber(applicationUser.getReferrerAccountNumber());
        if (user == null) {
            response.setCode(RetCode.ERROR_ACCOUNT_NUMBER);
            return response;
        }
        applicationUser.setSubmitUserId(Integer.parseInt(userId)).setIsAudit(0).setReferrerUserId(user.getId());
        userDao.saveApplicationUser(applicationUser);

        //添加消息通知记录
        Message message = new Message();
        message.setUserId(applicationUser.getId()).setRecommendId(-1).setContent("您推荐["+applicationUser.getName()+"]申请成为供应商").setType(1).setSign(0);
        systemDao.insertMsg(message);
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response searchAccountNumber(String type, String accountNumber) {
        Response response = new Response();
        if (type.equals("1")) {
            List<Map<String, Object>> users = userDao.searchAccountNumber(accountNumber);
            response.setData(users);
            response.setCode(RetCode.SUCCESS);
            return response;
        } else {
            if (userDao.getUserByAccountNumber(accountNumber) > 0) {
                response.put("flag", false);
            } else {
                response.put("flag", true);
            }
            response.setCode(RetCode.SUCCESS);
            return response;
        }
    }

    @Override
    public Response applicationUserList(Integer page, Integer size, Integer userCateId,
                                        String key, String isAudit, String type) {
        Response response = new Response();

        String userId = null;
        if (type != null) {
            userId = sessionUserUtil.getUser().getId().toString();
        }

        Integer start = (page - 1) * size;
        List<Map<String, Object>> user = userDao.applicationUserList(start, size, userCateId, key, isAudit, userId);
        Integer totalNum = userDao.applicationUserAmount(userCateId, key, isAudit, userId);
        PageResult<Map<String, Object>> pageList = new PageResult<>(user, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    public Response getUserInfo() {
        Response response = new Response();

        //从session中获取userId
        String userId = sessionUserUtil.getUser().getId().toString();

        Map<String, Object> userMap = userDao.getUserInfoByUserId(userId);
        if (!userMap.isEmpty()) {
            if (userMap.get("status").equals(UserStatus.NO_AUDIT.getType())) {
                response.setCode(RetCode.USER_NO_AUDIT);
                return response;
            }
            if (userMap.get("status").equals(UserStatus.REFUSE.getType())) {
                response.setCode(RetCode.USER_REFUSE);
                return response;
            }
            response.setData(userId);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response updateUser(String nickname, String headImg) {
        Response response = new Response();

        //从session中获取userId
        String userId = sessionUserUtil.getUser().getId().toString();

        User user = userDao.selectByPrimaryKey(userId);
        if (null != nickname) {
            user.setNickname(nickname);
        }
        if (null != headImg) {
            user.setHeadImg(headImg);
        }
        userDao.updateByPrimaryKeySelective(user);
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response updatePassword(String oldPassword, String newPassword, String newTwoPassword) {
        Response response = new Response();

        if (!newPassword.equals(newTwoPassword)) {
            response.setCode(RetCode.DIFFERENT_PASSWORD);
            return response;
        }

        //从session中获取userId
        String userId = sessionUserUtil.getUser().getId().toString();

        User user = userDao.selectByPrimaryKey(userId);
        String pwd = PasswordHelper.encryptPassword(oldPassword, user.getAccountNumber());
        if (!user.getPassword().equals(pwd)) {
            response.setCode(RetCode.ERROR_PASSWORD);
            return response;
        }
        if (oldPassword.equals(newPassword)) {
            response.setCode(RetCode.SAME_OLD_PASSWORD);
            return response;
        }
        user.setPassword(PasswordHelper.encryptPassword(newPassword, user.getAccountNumber()));
        userDao.updateByPrimaryKeySelective(user);

        //退出当前账号
        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        response.setCode(RetCode.SUCCESS);
        return response;


    }

    @Override
    public Response getUserAddress(String userId) {
        Response response = new Response();

        //从session中获取userId
        if (userId == "" || userId == null) {
            userId = sessionUserUtil.getUser().getId().toString();
        }
        List<UserAddress> userAddresses = userAddressDao.getUserAddress(userId);
        if (!userAddresses.isEmpty()) {
            response.setCode(RetCode.SUCCESS);
            response.setData(userAddresses);
        } else {
            response.setCode(RetCode.NOT_ADDRESS);
        }
        return response;
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Response userAddressSave(UserAddress userAddress) {
        Response response = new Response();
        String userId;
        //从session中获取userId
        if (userAddress.getUserId() == null) {
            userId = sessionUserUtil.getUser().getId().toString();
            userAddress.setUserId(Integer.parseInt(userId));
        } else {
            userId = String.valueOf(userAddress.getUserId());
        }

        if (userAddress.getIsDefault() == 1) {
            UserAddress userAddress1 = userAddressDao.getUserIsDefaultAddress(userId, 1);
            if (null != userAddress1) {
                userAddress1.setIsDefault(0);
                userAddressDao.update(userAddress1);
            }
        }
        if (userAddress.getId() != null) {
            userAddressDao.update(userAddress);
        } else {
            userAddressDao.insert(userAddress);
        }
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response deleteUserAddress(String id) {
        Response response = new Response();
        userAddressDao.deleteUserAddress(id);
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response userList(Integer page, Integer size, Integer roleId, String key) {
        Response response = new Response();

        Integer start = (page - 1) * size;
        List<Map<String, Object>> user = userDao.userList(start, size, roleId, key);
        Integer totalNum = userDao.userListAmount(roleId, key);
        PageResult<Map<String, Object>> pageList = new PageResult<>(user, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    public Response userSave(String mobile, Integer roleId, String password, String nickname, String id) {
        Response response = new Response();

        User userOld = userDao.getUserByMobile(mobile);
        if (null != userOld) {
            response.setCode(RetCode.USER_MOBILE);
            return response;
        }
        if (null != id) {
            User user1 = userDao.selectByPrimaryKey(id);
            user1.setRoleId(roleId).setNickname(nickname);
            userDao.update(user1);
        } else {
            User user = new User();
            String accountNumber = GenerateUserAccountNumberUtils.generaateUserAccountNumber();
            UserCategory userCategory =  userCategoryDao.getUserCateInfo();
            user.setStatus(0).setRecommendReward(new BigDecimal(0)).setGoodsReward(new BigDecimal(0)).setReferrerId(-1).setNickname(nickname)
                    .setIsAudit(1).setPassword(PasswordHelper.encryptPassword(password, accountNumber))
                    .setAccountNumber(accountNumber).setUserCateId(userCategory.getId())
                    .setMobile(mobile).setRoleId(roleId).setType(UserType.HQ_USER.getType())
                    .setSuperiorId(-1);
            userDao.insert(user);
        }

        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response updatePasswordPc(String userId, String newPassword, String newTwoPassword) {
        Response response = new Response();

        if (!newPassword.equals(newTwoPassword)) {
            response.setCode(RetCode.DIFFERENT_PASSWORD);
            return response;
        }

        User user = userDao.selectByPrimaryKey(userId);

        if (null == user) {
            response.setCode(RetCode.NOT_USER);
            return response;
        }

        user.setPassword(PasswordHelper.encryptPassword(newPassword, user.getAccountNumber()));
        userDao.updateByPrimaryKeySelective(user);
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response inventoryUserList(Integer page, Integer size, Integer userCateId, String key) {
        Response response = new Response();

        //从session中获取账号
        String userId = sessionUserUtil.getUser().getId().toString();
        User user = userDao.selectByPrimaryKey(userId);

        if (user.getType() == UserType.HQ_USER.getType()) {
            response.setCode(RetCode.PERMISSION_DENIED);
            return response;
        }

        if (user.getFlag() != UserFlag.THE_MUNICIPAL_AGENTS.getType()) {
            response.setCode(RetCode.PERMISSION_DENIED);
            return response;
        }

        Integer start = (page - 1) * size;
        List<Map<String, Object>> userList = userDao.getUserByAddressAndFlagTwo(start, size, userCateId, user.getProvince(), user.getCity(),
                UserFlag.DISTRICT_LEVEL_AGENTS.getType(), UserFlag.FLAGSHIP_LEVEL_AGENTS.getType(), key);
        Integer totalNum = userDao.getUserByAddressAndFlagAmount(user.getProvince(), user.getCity(), userCateId,
                UserFlag.DISTRICT_LEVEL_AGENTS.getType(), UserFlag.FLAGSHIP_LEVEL_AGENTS.getType(), key);
        PageResult<Map<String, Object>> pageList = new PageResult<>(userList, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }
}
